<?php

namespace app\admin\controller\fssy;

use app\common\controller\Backend;
use think\Log;
use think\Db;
use Exception;
use think\exception\DbException;
use think\exception\PDOException;
use think\exception\ValidateException;
use app\common\library\Auth;
use app\common\library\RequestContext;
use DateTime;
use app\common\controller\Api;
use app\common\MyLibrary\Utils; // 引入工具类 application\admin\command\MyLibrary\Utils.php

/**
 * 护士基本信息管理
 *
 * @icon fa fa-circle-o
 */
class Nurseinfo extends Backend
{

    /**
     * Nurseinfo模型对象
     * @var \app\admin\model\fssy\Nurseinfo
     */
    protected $model = null;

    // 登录人员信息
    protected $loginer = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\fssy\Nurseinfo;
        $this->view->assign("genderDataList", $this->model->getGenderDataList());
        $this->view->assign("onJobList", $this->model->getOnJobList());

        // 获取当前登录人员信息
        $this->loginer = Utils::getLonginInfo($this->auth->getUserInfo(), $this->auth->getGroups());
        // Log::record('loginer = ' . json_encode($this->loginer));
    }

    public function index()
    {
        // 指定搜索字段，这里为“管理员用户名”和“日志ID”
        // $this->searchFields = ["gender_data"];

        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);

        //判断请求是否为Ajax，若不是则直接返回视图
        if (false === $this->request->isAjax()) {
            return $this->view->fetch();
        }

        //如果发送的来源是 Selectpage，则转发到 Selectpage
        if ($this->request->request('keyField')) {
            return $this->selectpage();
        }

        //解析请求参数，构建查询条件、排序规则及分页参数
        [$where, $sort, $order, $offset, $limit] = $this->buildparams();

        // groupPId  0 => '超级管理组'; 1 => '护理部'; 2 => '各个科室组'; 2 => '医保科';
        if ($this->loginer['groupPId'] >= 2) {
            $deparId = $this->loginer['departmentId'];
        } else {
            $deparId = 'ALL';
        }

        //执行查询，根据构建的查询条件、排序规则及分页参数获取数据列表
        $list = $this->model
            ->with(["dictsdepartment", "dictsjobtitle", "dictsusejobtitle", "dictsiniteducationbak", "dictseducationbak"])
            ->where($where)
            ->order($sort, $order);
        // 如果 deparId 不是 'ALL' 且不为 null，表示是各个科室组或医保科
        if ($deparId !== 'ALL' && $deparId !== null) {
            $list->where('department_id', $deparId);
        }
        // 执行查询，根据构建的查询条件、排序规则及分页参数获取数据列表
        $list = $list->paginate($limit);

        //构建返回结果，包括总记录数和当前页记录列表
        $result = ['total' => $list->total(), 'rows' => $list->items()];

        Log::record('auth = ' . json_encode($this->auth->getGroups()));

        return json($result);
    }

    /**
     * 添加数据
     *
     * 该方法处理数据添加请求，支持GET和POST方法访问
     * 对于POST请求，它会尝试验证数据并将其插入数据库
     */
    public function add()
    {
        // 检查请求是否为POST，如果不是则渲染视图
        if (false === $this->request->isPost()) {
            // 往前端传数据
            $this->view->assign('operater', $this->loginer['userName']);
            return $this->view->fetch();
        }
        // 获取POST请求中的数据
        $params = $this->request->post('row/a');
        // 验证参数是否为空，如果为空则抛出错误
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }

        // 预处理参数，排除不必要的字段
        $params = $this->preExcludeFields($params);

        // 如果设置了数据限制且自动填充字段，则将当前用户的ID添加到参数中
        if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
            $params[$this->dataLimitField] = $this->auth->id;
        }

        // 计算年龄
        if (isset($params['birth_date'])) {
            $params['age'] = Utils::calculateAge($params['birth_date']);
        }
        // 计算工作年限
        if (isset($params['start_work_date'])) {
            $params['work_years'] = Utils::calculateYearsMonths($params['start_work_date']);
        }
        // 计算在医院的年限
        if (isset($params['hospital_start_date'])) {
            $params['hospital_years'] = Utils::calculateYearsMonths($params['hospital_start_date']);
        }
        // 离职时间
        if (isset($params['off_job_date'])) {
            $params['off_job_date'] = $params['off_job_date'];
        }
        // 操作员
        if (isset($params['operator'])) {
            $params['operator'] = $params['operator'];
        }
        // 更新时间 ?????????????????????????????
        // if (isset($params['updatetime'])) {
        //     // 变成时间戳
        //     $params['updatetime'] = strtotime($params['updatetime']);
        // }


        // 初始化结果变量为false
        $result = false;
        // 开始数据库事务
        Db::startTrans();
        try {
            // 是否采用模型验证
            if ($this->modelValidate) {
                // 根据模型类名生成验证器类名
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                // 确定使用哪种验证场景
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
                // 执行验证，如果失败则抛出异常
                $this->model->validateFailException()->validate($validate);
            }
            // 尝试保存数据，如果成功则提交事务
            $result = $this->model->allowField(true)->save($params);
            Db::commit();
        } catch (ValidateException | PDOException | Exception $e) {
            // 如果发生异常则回滚事务，并显示错误信息
            Db::rollback();
            $this->error($e->getMessage());
        }
        // 如果数据保存失败则显示错误信息
        if ($result === false) {
            $this->error(__('No rows were inserted'));
        }
        // 数据保存成功，返回成功信息
        $this->success();
    }


    /**
     * 编辑数据
     *
     * @param mixed $ids 要编辑的数据的ID，可以是单个ID或ID数组
     */
    public function edit($ids = null)
    {
        // 获取指定ID的数据行
        $row = $this->model->get($ids);
        // 如果没有找到数据行，则显示错误消息
        if (!$row) {
            $this->error(__('No Results were found'));
        }

        // 获取管理员ID限制，用于数据权限控制
        $adminIds = $this->getDataLimitAdminIds();
        // 检查当前操作者是否有权限编辑该数据行
        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
        }

        // 如果不是POST请求，则渲染编辑页面
        if (false === $this->request->isPost()) {
            $this->view->assign('operater', $this->loginer['userName']);
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }

        // 获取POST请求中的数据
        $params = $this->request->post('row/a');
        // 如果提交的数据为空，则显示错误消息
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }

        // 预处理提交的数据，排除不需要的字段
        $params = $this->preExcludeFields($params);

        // 计算年龄
        if (isset($params['birth_date'])) {
            $params['age'] = Utils::calculateAge($params['birth_date']);
        }
        // 计算工作年限
        if (isset($params['start_work_date'])) {
            $params['work_years'] = Utils::calculateYearsMonths($params['start_work_date']);
        }
        // 计算在医院的年限
        if (isset($params['hospital_start_date'])) {
            $params['hospital_years'] = Utils::calculateYearsMonths($params['hospital_start_date']);
        }

        // 更新时间 ?????????????????????????????
        // if (isset($params['updatetime'])) {
        //     // 变成时间戳
        //     $params['updatetime'] = strtotime($params['updatetime']);
        // }

        // 在职状态 若为在职 则离职时间为空 若为非在职 则离职时间不为空
        $params['on_job'] == '在职' ? $params['off_job_date'] = null : $params['off_job_date'];
        // 操作员
        if (isset($params['operator'])) {
            $params['operator'] = $params['operator'];
        }

        // 初始化结果变量
        $result = false;

        // 开始数据库事务
        Db::startTrans();
        try {
            // 是否采用模型验证
            if ($this->modelValidate) {
                // 根据模型类名生成验证器类名
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                // 确定使用哪种场景的验证规则
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                // 对数据进行验证
                $row->validateFailException()->validate($validate);
            }

            // 更新数据行，并使用事务确保数据一致性
            $result = $row->allowField(true)->save($params);
            // 提交事务
            Db::commit();
        } catch (ValidateException | PDOException | Exception $e) {
            // 回滚事务
            Db::rollback();
            // 显示错误消息
            $this->error($e->getMessage());
        }

        // 如果数据更新失败，则显示错误消息
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }

        // 数据更新成功，显示成功消息
        $this->success();
    }

    // 生成季度报表 表格数据 插入数据库
    public function generatetable()
    {
        // 判断是否post请求
        if ($this->request->isPost()) {
            $this->model = new \app\admin\model\fssy\Nurseinfo;
            // 获取最小的 updatetime 数据
            $min_updatetime_data = $this->model->order('updatetime', 'asc')->limit(1)->find();
            // 获取最大的 updatetime 数据
            $max_updatetime_data = $this->model->order('updatetime', 'desc')->limit(1)->find();

            // 时间戳转换成时间 返回2022-05-10 12:51:18格式
            $min_updatetime = date('Y-m-d H:i:s', $min_updatetime_data['updatetime']);
            // 时间戳转换成时间 返回2024-12-07 16:01:29格式
            $max_updatetime = date('Y-m-d H:i:s', $max_updatetime_data['updatetime']);

            // 最小 取前4位字符 年 = 2022
            $min_updatetime_year = substr($min_updatetime, 0, 4);
            // 最小 取前5位和6位字符 月 = 05
            $min_updatetime_month = substr($min_updatetime, 5, 2);
            // 最大 取前4位字符 2024
            $max_updatetime_year = substr($max_updatetime, 0, 4);
            // 最大 取前5位和6位字符 月 = 12
            $max_updatetime_month = substr($max_updatetime, 5, 2);

            // 0:        // "2024-01-01 ~ 2024-03-31 一季度"
            // 1:        // "2024-04-01 ~ 2024-06-30 二季度"
            // 2:        // "2024-07-01 ~ 2024-09-30 三季度"
            // 3:        // "2024-10-01 ~ 2024-12-31 四季度"
            // @@@  $max_updatetime_month = 2022; $min_updatetime_month = 05; $max_updatetime_year = 2024; $max_updatetime_month = 12;
            $quarterArr = Utils::generateQuarterDates($min_updatetime_year, $min_updatetime_month, $max_updatetime_year, $max_updatetime_month);

            /**
             *  [
             * 0:"2024-01-01 00:00:00~2024-03-31 23:59:59"
             * 1:"2024-04-01 00:00:00~2024-06-30 23:59:59"
             * 2:"2024-07-01 00:00:00~2024-09-30 23:59:59"
             * 3:"2024-10-01 00:00:00~2024-12-31 23:59:59"
             *  ]
             */
            $dateTimeArr = Utils::convertQuarterDates($quarterArr);

            /***
             * [
                { "start": 1704038400, "end": 1711900799 },
                { "start": 1711900800, "end": 1719763199 },
                { "start": 1719763200, "end": 1727711999 },
                { "start": 1727712000, "end": 1735660799 }
            ]
             */
            $dateStampsArr = Utils::dateTimeArrToTimestamps($dateTimeArr);
            // Log::record('$dateStampsArr = ' . json_encode($dateStampsArr));

            // 查询数据 - 聘任职称
            $this->model = new \app\admin\model\dicts\Jobtitle;
            $jobTitle = $this->model->field("jobtitle")->select();
            $jobTitleArr = json_decode(json_encode($jobTitle), true); // 将查询结果转换为数组
            // json_encode 是 PHP 中的一个内置函数，用于将一个值转换为 JSON 格式字符串
            //    [ { "jobtitle": "护士" },
            //     { "jobtitle": "护师" },
            //     { "jobtitle": "主管护师" },
            //     { "jobtitle": "副主任护师" },
            //     { "jobtitle": "主任护师" }]
            // 
            // $jobTitleArr = Array
            // (   [0] => Array  (            [jobtitle] => 护士       )
            //     [1] => Array  (            [jobtitle] => 护师       )
            //     [2] => Array  (            [jobtitle] => 主管护师    )
            //     [3] => Array  (            [jobtitle] => 副主任护师  )
            //     [4] => Array  (            [jobtitle] => 主任护师    ))
            // Log::record('$jobTitleArr = ' .  print_r($jobTitleArr, true));

            // 查询数据 - 聘任职称
            $this->model = new \app\admin\model\dicts\Educationbak;
            $educationBak = $this->model->field("educationbak")->select();
            $educationBakArr = json_decode(json_encode($educationBak), true); // 将查询结果转换为数组

            // 查询数据 - 年金
            $this->model = new \app\admin\model\dicts\Yearpay();
            $yearPay = $this->model->field("yearpay")->select();
            $yearPaykArr = json_decode(json_encode($yearPay), true); // 将查询结果转换为数组

            // 清空表格 nsqtrt6jt nsqtrt6eb
            Db::name('fssy_nsqtrt6jt')->delete(true);
            Db::name('fssy_nsqtrt6eb')->delete(true);
            Db::name('fssy_nsqtrt6nz')->delete(true);

            // 遍历 $dateStampsArr，进行批量查询
            foreach ($dateStampsArr as $index => $item) {
                $this->model = new \app\admin\model\fssy\Nurseinfo;
                // 每次循环时重新初始化统计数组
                // $jobTitleCounts = [
                //     "护士" => 0,
                //     "护师" => 0,
                //     "主管护师" => 0,
                //     "副主任护师" => 0,
                //     "主任护师" => 0
                // ];
                $jobTitleCounts = Utils::arrSetZero($jobTitleArr, "jobtitle");
                $educationBakCounts = Utils::arrSetZero($educationBakArr, "educationbak");
                $yearPayCounts = Utils::arrSetZero($yearPaykArr, "yearpay");
                // Log::record('$yearPayCounts = ', json_encode($yearPayCounts));

                // 查询数据
                $data = $this->model
                    ->with(["dictsusejobtitle", "dictseducationbak"])
                    ->whereTime('fa_fssy_nurseinfo.updatetime', '>=', $item["start"])
                    ->whereTime('fa_fssy_nurseinfo.updatetime', '<=', $item["end"])
                    // ->where("department_id", '=', 1)
                    ->select();
                // Log::record('$data = ' . json_encode($data));

                // 如果有数据，统计职称数量
                foreach ($data as $nurse) {
                    $jobTitle = $nurse->dictsusejobtitle->jobtitle; // 假设职称保存在 dictsusejobtitle 的 jobtitle 属性中
                    $educationBak = $nurse->dictseducationbak->educationbak; // 假设职称保存在 dictsusejobtitle 的 jobtitle 属性中
                    $yearPay = Utils::calcYearsStep($nurse->work_years); // 假设职称保存在 dictsusejobtitle 的 jobtitle 属性中
                    if (array_key_exists($jobTitle, $jobTitleCounts)) {
                        $jobTitleCounts[$jobTitle]++;
                    }
                    if (array_key_exists($educationBak, $educationBakCounts)) {
                        $educationBakCounts[$educationBak]++;
                    }
                    if (array_key_exists($yearPay, $yearPayCounts)) {
                        $yearPayCounts[$yearPay]++;
                    }
                }
                // 记录统计结果
                $jobTitleItemArr = json_decode(json_encode($jobTitleCounts), true);
                $educationBakItemArr = json_decode(json_encode($educationBakCounts), true);
                $yearPayItemArr = json_decode(json_encode($yearPayCounts), true);
                Log::record('时间区间 [' . date('Y-m-d H:i:s', $item["start"]) . ' - ' . date('Y-m-d H:i:s', $item["end"]) . '] 职称数量: ' . print_r($jobTitleItemArr, true));
                // 往数据库中插入数据 Nsqtrt6jt
                Utils::insertNurse6DB($quarterArr, $jobTitleItemArr, $index, 'jobTitle');
                Utils::insertNurse6DB($quarterArr, $educationBakItemArr, $index, 'education');
                Utils::insertNurse6DB($quarterArr, $yearPayItemArr, $index, 'yearPay');
            }
            return json(['msg' => "OK"]);
        }
    }

    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */
}
